#ifndef RECTANGLE_HPP
#define RECTANGLE_HPP

/********************************************************************
	created:	2011/01/14
	filename: 	E:\C++\Red\src\Utils\Math\Rectangle.hpp
	author:		Red
	
	purpose:	2D Rectangle Class with Intersection functions
*********************************************************************/

#include "Vector2.hpp"

namespace red {
	/// Three possible results of an Intersection
	enum IntersectionResult{
		IR_In,		
		IR_Out,		
		IR_Intersect
	};

	/// 2D Rectangle Class
	class Rectangle{
	public:
		/// Default Ctor
		Rectangle() : mOrigin(Vector2F::ZERO), mEnd(Vector2F::ZERO) {}

		/// Ctor from 4 boundaries
		Rectangle(f32 top, f32 left, f32 width, f32 height);

		/// Ctor from Top-Left and Size Vectors
		template<class T>
		Rectangle(const Vector2<T> &pTopLeft, const Vector2<T> &pSize);

		/// Initialize the rectangle from 4 boundaries
		void Set(f32 top, f32 left, f32 width, f32 height);
		
		// Getters
			f32 Left()				 const	{ return mOrigin.x; }
			f32 Top()				 const	{ return mOrigin.y; }
			f32 Right()				 const	{ return mEnd.x; }
			f32 Bottom()			 const	{ return mEnd.y; }

			f32 Width()				 const	{ return mEnd.x - mOrigin.x; }
			f32 Height()			 const	{ return mEnd.y - mOrigin.y; }
			const Vector2F& Origin() const	{ return mOrigin; }
			const Vector2F& End()	 const	{ return mEnd; }
			Vector2F Size()			 const	{ return mEnd - mOrigin; }

		// Setters
			void Left(f32 pVal)				{ mOrigin.x = pVal; }
			void Top(f32 pVal)				{ mOrigin.y = pVal; }
			void Right(f32 pVal)			{ mEnd.x = pVal; }
			void Bottom(f32 pVal)			{ mEnd.y = pVal; }

			void SetWidth(f32 pVal)			{ mEnd.x = mOrigin.x + pVal; }
			void SetHeight(f32 pVal)		{ mEnd.y = mOrigin.y + pVal; }
			void SetSize(const Vector2F &pV){ mEnd = mOrigin + pV; }
			void SetPosition(const Vector2F &pV);
			

		/// Returns the intersection type between a point and this rectangle
		IntersectionResult Intersects(const Vector2F &pPoint) const;
		
		/// Returns the intersection type between another and this rectangle
		IntersectionResult Intersects(const Rectangle &pRect) const;

		bool operator==(const Rectangle &pRect) const { return mEnd == pRect.mEnd && mOrigin == pRect.mOrigin; }
		bool operator!=(const Rectangle &pRect) const { return !((*this) == pRect); }

		/// Affectation operator
		void operator=(const Rectangle &pRect) { mOrigin = pRect.mOrigin; mEnd = pRect.mEnd; }
		
		friend std::istream& operator>> (std::istream &iss, Rectangle &Rect);
		friend std::ostream& operator<< (std::ostream &oss, const Rectangle &Rect);

		// Data
	private:
		Vector2F mOrigin;
		Vector2F mEnd;
	};

	inline std::istream& operator>>(std::istream& iss, Rectangle& Rect){
		return iss >> Rect.mOrigin >> Rect.mEnd;
	}

	inline std::ostream& operator<<(std::ostream& oss, const Rectangle& Rect){
		return oss << Rect.mOrigin << " " << Rect.mEnd;
	}
}
#endif
